package net.da.client.component;

import java.util.HashMap;
import java.util.Map;

import net.da.client.common.component.ComponentDispatcher;
import net.da.client.common.component.ComponentDispatcherImpl;
import net.da.client.common.component.ComponentImpl;
import net.da.client.constants.DAConstants;
import net.da.client.dto.DaErrorData;
import net.da.client.dto.LoginRequestData;
import net.da.client.dto.LoginResponseData;
import net.da.client.service.AuthorizeService;
import net.da.client.service.AuthorizeServiceAsync;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class LoginComponent extends ComponentImpl {

	private VerticalPanel verticalPanel;
	private TextBox loginTextBox;
	private PasswordTextBox passwordTextBox;
	private TextBox organizationTextBox;
	private Label loginMessageLabel;
	private Label passwordMessageLabel;
	private Label organizationMessageLabel;

	public void onHide() {
	}

	public void onShow() {
		buildLayout();
	}

	protected void buildHeader() {
		HorizontalPanel hp = new HorizontalPanel();
		hp.setBorderWidth(1);
		hp.setHeight("30px");
		hp.setWidth("600px");
		Label label = new Label("Header");
		hp.add(label);
		verticalPanel.add(hp);
		SimplePanel sp = new SimplePanel();
		sp.setHeight("10px");
		verticalPanel.add(sp);
	}

	protected void buildFooter() {

		SimplePanel sp = new SimplePanel();
		sp.setHeight("10px");
		verticalPanel.add(sp);

		HorizontalPanel hp = new HorizontalPanel();
		hp.setBorderWidth(1);
		hp.setHeight("30px");
		hp.setWidth("600px");
		Label label = new Label("Footer");
		hp.add(label);
		verticalPanel.add(hp);
	}

	protected void buildBody() {

		loginTextBox = new TextBox();
		passwordTextBox = new PasswordTextBox();
		organizationTextBox = new TextBox();
		loginMessageLabel = new Label();
		loginMessageLabel.setStyleName("errorMessage");
		passwordMessageLabel = new Label();
		passwordMessageLabel.setStyleName("errorMessage");
		organizationMessageLabel = new Label();
		organizationMessageLabel.setStyleName("errorMessage");

		Button signInButton = new Button("Sing in");

		FlexTable flexTable = new FlexTable();

		flexTable.setWidget(0, 1, new Label("User name: "));
		flexTable.setWidget(0, 2, loginTextBox);
		flexTable.setWidget(1, 1, loginMessageLabel);
		flexTable.getFlexCellFormatter().setColSpan(1, 1, 2);

		flexTable.setWidget(2, 1, new Label("Password: "));
		flexTable.setWidget(2, 2, passwordTextBox);
		flexTable.setWidget(3, 1, passwordMessageLabel);
		flexTable.getFlexCellFormatter().setColSpan(3, 1, 2);

		flexTable.setWidget(4, 1, new Label("Organization unit: "));
		flexTable.setWidget(4, 2, organizationTextBox);
		flexTable.setWidget(5, 1, organizationMessageLabel);
		flexTable.getFlexCellFormatter().setColSpan(5, 1, 2);

		flexTable.setWidget(6, 1, signInButton);
		flexTable.getFlexCellFormatter().setColSpan(3, 1, 2);

		verticalPanel.add(flexTable);

		signInButton.addClickListener(new ClickListener() {

			public void onClick(Widget sender) {
				onSingIn();
			}

		});
	}

	private void onSingIn() {

		boolean hasErrors = false;
		String login = loginTextBox.getText();
		loginMessageLabel.setText("");
		if (login == null || login.length() <= 0) {
			loginMessageLabel.setText("Required field cannot be left blank");
			hasErrors = true;
		}

		passwordMessageLabel.setText("");
		String password = passwordTextBox.getText();
		if (password == null || password.length() <= 0) {
			passwordMessageLabel.setText("Required field cannot be left blank");
			hasErrors = true;
		}

		organizationMessageLabel.setText("");
		String organization = organizationTextBox.getText();
		if (organization == null || organization.length() <= 0) {
			organizationMessageLabel
					.setText("Required field cannot be left blank");
			hasErrors = true;
		}

		AuthorizeServiceAsync authorizeService = AuthorizeService.Util
				.getInstance();
		LoginRequestData loginRequest = new LoginRequestData();
		loginRequest.setUserName(login);
		loginRequest.setPassword(password);
		loginRequest.setOrganizationUnit(organization);

		if (hasErrors) {
			return;
		}

		authorizeService.loginUser(loginRequest, new AsyncCallback() {

			public void onFailure(Throwable caught) {
				organizationMessageLabel.setText("Unknown server error!");
			}

			public void onSuccess(Object result) {

				LoginResponseData response = (LoginResponseData) result;
				if (response.hasErrors()) {
					DaErrorData daError = (DaErrorData) response.getErrors().get(0);
					String message = daError.getMessage();
					organizationMessageLabel.setText(message);

				} else if (response.isWrongOrganisationUnit()) { 
					organizationMessageLabel.setText("Organisation unit is not found!");
				} else if (response.isAuthenticationFailed()) {
					organizationMessageLabel.setText("Authentication information is not correct!");
				} else {		
					ComponentDispatcher dispatcher = ComponentDispatcherImpl
							.getInstance();
					String authorizationCode = response.getAuthorizationCode();
					Map args = new HashMap();
					args.put("authorizationCode", authorizationCode);					
					dispatcher
							.jumpTo(DAConstants.COMPONENTS_NAMES.HOME_COMPONENT, args);
				}
			}
		});

	}

	protected void buildLayout() {

		verticalPanel = new VerticalPanel();
		buildHeader();
		buildBody();
		buildFooter();
		Panel root = getComponentRoot();
		root.clear();
		root.add(verticalPanel);
	}

}
